package com.zzx.schoolfellow.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vdurmont.emoji.EmojiParser;
import com.zzx.schoolfellow.mapper.*;
import com.zzx.schoolfellow.model.dto.CreateTopicDTO;
import com.zzx.schoolfellow.model.entity.*;
import com.zzx.schoolfellow.model.vo.PostVO;
import com.zzx.schoolfellow.model.vo.ProfileVO;
import com.zzx.schoolfellow.service.IBmsPostService;
import com.zzx.schoolfellow.service.IBmsTagService;
import com.zzx.schoolfellow.service.IUmsUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: schoolfeoolw_backend
 * @description:
 * @author: zzx
 * @create: 2023-03-14 22:13
 **/

@Service
public class IBmsPostServiceImpl extends ServiceImpl<BmsTopicMapper, BmsPost> implements IBmsPostService {
    @Resource
    private BmsTagMapper bmsTagMapper;
    @Resource
    private UmsUserMapper umsUserMapper;
    @Resource
    private PostMapper postMapper;
    @Resource
    private SensitiveWordMapper sensitiveWordMapper;

    @Resource
    @Lazy
    private IBmsTagService iBmsTagService;

    @Resource
    private IUmsUserService iUmsUserService;

    @Resource
    private com.zzx.schoolfellow.service.IBmsTopicTagService IBmsTopicTagService;
    @Override
    public Page<PostVO> getList(Page<PostVO> page, String tab, String status) {
        QueryWrapper<BmsPost> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", status);
        // 查询话题
        Page<PostVO> iPage = this.baseMapper.selectListAndPage(page, tab);
        // 查询话题的标签
        setTopicTags(iPage);
        return iPage;
    }

    public List<BmsPost> getAllPosts() {
        return postMapper.getAllPosts();
    }

    public BmsPost getPostById(Long id) {
        return postMapper.getPostById(id);
    }
    public BmsPost updatePost(Long id, BmsPost post) {
        BmsPost oldPost = postMapper.getPostById(id);
        if (oldPost == null) {
            throw new IllegalArgumentException("Invalid post id");
        }
        oldPost.setTitle(post.getTitle());
        oldPost.setContent(post.getContent());
        oldPost.setStatus(post.getStatus());
        postMapper.updatePost(oldPost);
        return oldPost;
    }

    public void deletePost(Long id) {
        postMapper.deletePost(id);
    }

    public BmsPost createPost(BmsPost post) {
        post.setStatus("待审核");
        postMapper.createPost(post);
        return post;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BmsPost create(CreateTopicDTO dto, UmsUser user) {
        BmsPost topic1 = this.baseMapper.selectOne(new LambdaQueryWrapper<BmsPost>().eq(BmsPost::getTitle, dto.getTitle()));
        Assert.isNull(topic1, "话题已存在，请修改");

        // 封装
        BmsPost topic = BmsPost.builder()
                .userId(user.getId())
                .title(dto.getTitle())
                .content(EmojiParser.parseToAliases(dto.getContent()))
                .createTime(new Date())
                .status("0")
                .build();
        topic.setContent(checkAndReplaceSensitiveWords(topic.getContent()));
        this.baseMapper.insert(topic);

        // 用户积分增加
        int newScore = user.getScore() + 1;
        umsUserMapper.updateById(user.setScore(newScore));

        // 标签
        if (!ObjectUtils.isEmpty(dto.getTags())) {
            // 保存标签
            List<BmsTag> tags = iBmsTagService.insertTags(dto.getTags());
            // 处理标签与话题的关联
            IBmsTopicTagService.createTopicTag(topic.getId(), tags);
        }

        return topic;
    }

    @Override
    public Map<String, Object> viewTopic(String id) {
        Map<String, Object> map = new HashMap<>(16);
        BmsPost topic = this.baseMapper.selectById(id);
        Assert.notNull(topic, "当前话题不存在,或已被作者删除");
        if (topic.getStatus().equals("1")) {
            // 查询话题详情
            topic.setView(topic.getView() + 1);
            this.baseMapper.updateById(topic);
            // emoji转码
            topic.setContent(EmojiParser.parseToUnicode(topic.getContent()));
            map.put("topic", topic);
            // 标签
            QueryWrapper<BmsTopicTag> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(BmsTopicTag::getTopicId, topic.getId());
            Set<String> set = new HashSet<>();
            for (BmsTopicTag articleTag : IBmsTopicTagService.list(wrapper)) {
                set.add(articleTag.getTagId());
            }
            List<BmsTag> tags = iBmsTagService.listByIds(set);
            map.put("tags", tags);

            // 作者

            ProfileVO user = iUmsUserService.getUserProfile(topic.getUserId());
            map.put("user", user);
            return map;
        } else {
            return null;
        }

    }

    @Override
    public List<BmsPost> getRecommend(String id) {
        return this.baseMapper.selectRecommend(id);
    }
    @Override
    public Page<PostVO> searchByKey(String keyword, Page<PostVO> page) {
        // 查询话题
        Page<PostVO> iPage = this.baseMapper.searchByKey(page, keyword);
        // 查询话题的标签
        setTopicTags(iPage);
        return iPage;
    }

    private void setTopicTags(Page<PostVO> iPage) {
        iPage.getRecords().forEach(topic -> {
            List<BmsTopicTag> topicTags = IBmsTopicTagService.selectByTopicId(topic.getId());
            if (!topicTags.isEmpty()) {
                List<String> tagIds = topicTags.stream().map(BmsTopicTag::getTagId).collect(Collectors.toList());
                List<BmsTag> tags = bmsTagMapper.selectBatchIds(tagIds);
                topic.setTags(tags);
            }
        });
    }

    public String checkAndReplaceSensitiveWords(String content) {
        List<String> words = splitContent(content);
        QueryWrapper<SensitiveWord> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("word");
        queryWrapper.orderByAsc("id");
        List<SensitiveWord> sensitiveWords = sensitiveWordMapper.selectList(queryWrapper);
        StringBuilder sb = new StringBuilder(content);
        for (SensitiveWord sensitiveWord : sensitiveWords) {
            String word = sensitiveWord.getWord();
            if (content.contains(word)) {
                int index = sb.indexOf(word);
                while (index != -1) {
                    sb.replace(index, index + word.length(), StringUtils.repeat("*", word.length()));
                    index = sb.indexOf(word, index + 1);
                }
            }
        }
        return sb.toString();
    }

    // 将文本分字切割
    private List<String> splitContent(String content) {
        List<String> words = new ArrayList<>();
        for (int i = 0; i < content.length(); i++) {
            words.add(String.valueOf(content.charAt(i)));
        }
        return words;
    }
}
